package org.robert.export_client.excel.metadata;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.robert.export_client.excel.builder.ExcelHeadBuilder;
import org.robert.export_client.excel.entity.CellStyleEntity;
import org.robert.export_client.excel.impl.ExcelHeadService;
import org.robert.export_client.excel.impl.ExcelWriteByDataService;
import org.robert.export_client.excel.util.ExcelUtil;

import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * @Description
 * @Author robert
 * @Date 2024/1/20 20:52
 **/
@Data
@Slf4j
public abstract class AbstractSheetBuilder {

    protected boolean flag = true;

    protected AbstractWorkbookBuilder workbookBuilder;

    protected HSSFSheet sheet;

    protected ExcelHeadBuilder excelHeadBuilder;


    protected Class<?> clazz;

    protected  Map<String, Map<String, String>> dictMap;

    protected ExcelWriteByDataService writeByDataService;

    public AbstractSheetBuilder(AbstractWorkbookBuilder workbookBuilder, HSSFSheet sheet, Class<?> clazz,
                                     Map<String, Map<String, String>> dictMap) throws Exception {
        this.sheet = sheet;
        this.workbookBuilder = workbookBuilder;
        this.clazz = clazz;
        this.dictMap = dictMap;
        // 构建头
        this.excelHeadBuilder = ExcelHeadBuilder.of(this.clazz, this.dictMap);
        List<ExcelHeadEntity> headEntityList = this.excelHeadBuilder.getExcelHeadEntityList();

        // 创建单元格样式
        CellStyle titleStyle = this.workbookBuilder.workbook.createCellStyle();
        titleStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); // 设置背景色（可选）
        titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 设置填充方式（可选）
        // 创建字体并设置加粗
        Font boldFont = this.workbookBuilder.workbook.createFont();
        boldFont.setBold(true); // 设置字体加粗
        boldFont.setFontHeightInPoints((short) 12); // 设置字体大小（可选）
        titleStyle.setFont(boldFont);

        ExcelHeadService.doHead(headEntityList, this.sheet, titleStyle);
        this.writeByDataService = new ExcelWriteByDataService(this.sheet);
    }

    public AbstractSheetBuilder(AbstractWorkbookBuilder workbookBuilder, HSSFSheet sheet, Class<?> clazz,
                                Map<String, Map<String, String>> dictMap, CellStyleEntity titleStyle) throws Exception {
        this.sheet = sheet;
        this.workbookBuilder = workbookBuilder;
        this.clazz = clazz;
        this.dictMap = dictMap;
        // 构建头
        this.excelHeadBuilder = ExcelHeadBuilder.of(this.clazz, this.dictMap);
        List<ExcelHeadEntity> headEntityList = this.excelHeadBuilder.getExcelHeadEntityList();
        ExcelHeadService.doHead(headEntityList, this.sheet, ExcelUtil.parseCellStyle(this.workbookBuilder.workbook,titleStyle), titleStyle.getRowHeight());
        this.writeByDataService = new ExcelWriteByDataService(this.sheet);
    }

    public void doWrite(List<?> data) throws Exception {
        // 创建内容
        List<ExcelHeadEntity> headEntityList = this.excelHeadBuilder.getExcelHeadEntityList();

        writeByDataService.doWrite(data, clazz, headEntityList);
    }

    public void doWrite(List<?> data, CellStyleEntity cellStyle) throws Exception {
        // 创建内容
        List<ExcelHeadEntity> headEntityList = this.excelHeadBuilder.getExcelHeadEntityList();

        writeByDataService.doWrite(data, clazz, headEntityList, ExcelUtil.parseCellStyle(this.workbookBuilder.workbook, cellStyle), cellStyle.getRowHeight());

    }

    public AbstractWriteSheet build(){
        this.flag = false;
        return new AbstractWriteSheet(this);
    }

    public void finish(){
        this.flag = true;
        try {
            // workbookBuilder.response.flushBuffer();
            workbookBuilder.workbook.write(workbookBuilder.response.getOutputStream());
            log.info("sheet {} write finished", sheet.getSheetName());
        }catch (IOException e){
            log.error(e.getMessage(),e);
        }
    }

}
